package com.wusiwei.service.impl;

import com.wusiwei.common.BusinessException;
import com.wusiwei.common.PageRequest;
import com.wusiwei.common.PageResult;
import com.wusiwei.common.Result;
import com.wusiwei.entity.Invoice;
import com.wusiwei.entity.InvoiceDetail;
import com.wusiwei.entity.Order;
import com.wusiwei.mapper.InvoiceDetailMapper;
import com.wusiwei.mapper.InvoiceMapper;
import com.wusiwei.service.InvoiceService;
import com.wusiwei.service.MatchService;
import com.wusiwei.service.OrderService;
import com.wusiwei.util.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 发票服务实现类
 */
@Slf4j
@Service
public class InvoiceServiceImpl implements InvoiceService {

    @Autowired
    private InvoiceMapper invoiceMapper;

    @Autowired
    private InvoiceDetailMapper invoiceDetailMapper;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private OrderService orderService;

    @Autowired
    private MatchService matchService;

    /**
     * 更新发票
     *
     * @param invoice 发票对象
     * @return 操作结果
     */
    @Override
    @Transactional
    public Result<Invoice> update(Invoice invoice) {
        try {
            // 检查发票是否存在
            Invoice existInvoice = invoiceMapper.findById(invoice.getId());
            if (existInvoice == null) {
                return Result.error("发票不存在");
            }

            // 检查发票号码是否已被其他发票使用
            if (invoice.getInvoiceNumber() != null && !invoice.getInvoiceNumber().equals(existInvoice.getInvoiceNumber())) {
                Invoice otherInvoice = invoiceMapper.findByInvoiceNumber(invoice.getInvoiceNumber());
                if (otherInvoice != null && !otherInvoice.getId().equals(invoice.getId())) {
                    return Result.error("发票号码已被其他发票使用");
                }
            }

            // 对部分更新的处理，保留原有值
            if (invoice.getCategory() == null) invoice.setCategory(existInvoice.getCategory());
            if (invoice.getInvoiceNumber() == null) invoice.setInvoiceNumber(existInvoice.getInvoiceNumber());
            if (invoice.getIssueDate() == null) invoice.setIssueDate(existInvoice.getIssueDate());
            if (invoice.getPurchaserInfo() == null) invoice.setPurchaserInfo(existInvoice.getPurchaserInfo());
            if (invoice.getSellerInfo() == null) invoice.setSellerInfo(existInvoice.getSellerInfo());
            if (invoice.getRemarks() == null) invoice.setRemarks(existInvoice.getRemarks());
            if (invoice.getIssuer() == null) invoice.setIssuer(existInvoice.getIssuer());
            if (invoice.getFilePath() == null) invoice.setFilePath(existInvoice.getFilePath());
            if (invoice.getTotalAmount() == null) invoice.setTotalAmount(existInvoice.getTotalAmount());
            if (invoice.getTotalTax() == null) invoice.setTotalTax(existInvoice.getTotalTax());
            if (invoice.getTotalAmountWithTax() == null)
                invoice.setTotalAmountWithTax(existInvoice.getTotalAmountWithTax());

            // 打印调试信息
            log.info("更新前的发票: {}", existInvoice);
            log.info("更新后的发票: {}", invoice);

            // 更新发票基本信息
            invoiceMapper.update(invoice);
            log.info("更新发票基本信息完成");

            // 更新发票详情
            List<InvoiceDetail> details = invoice.getDetails();
            if (details != null) {
                // 先查询原有的明细
                List<InvoiceDetail> oldDetails = invoiceDetailMapper.findByInvoiceId(invoice.getId());
                log.info("更新前的发票明细数量: {}", oldDetails.size());

                // 先删除原有详情
                try {
                    int deletedRows = invoiceDetailMapper.deleteByInvoiceId(invoice.getId());
                    log.info("已删除发票明细: {} 条", deletedRows);
                } catch (Exception e) {
                    log.error("删除原有发票明细失败", e);
                    throw e;
                }

                // 保存新的详情
                if (!details.isEmpty()) {
                    log.info("需要重新插入的发票明细数量: {}", details.size());

                    for (InvoiceDetail detail : details) {
                        detail.setInvoiceId(invoice.getId());
                        log.info("准备插入发票明细: {}", detail);
                    }

                    try {
                        int insertedRows = invoiceDetailMapper.batchInsert(details);
                        log.info("已插入发票明细: {} 条", insertedRows);
                    } catch (Exception e) {
                        log.error("插入新的发票明细失败", e);
                        throw e;
                    }
                } else {
                    log.warn("没有新的发票明细需要插入");
                }
            } else {
                log.warn("更新时未提供发票明细");
            }

            // 返回更新后的完整信息
            Invoice updatedInvoice = invoiceMapper.findById(invoice.getId());
            List<InvoiceDetail> updatedDetails = invoiceDetailMapper.findByInvoiceId(invoice.getId());
            log.info("更新后查询到的发票明细数量: {}", updatedDetails.size());
            updatedInvoice.setDetails(updatedDetails);
            return Result.success(updatedInvoice);
        } catch (Exception e) {
            log.error("更新发票失败", e);
            return Result.error("更新发票失败: " + e.getMessage());
        }
    }

    /**
     * 删除发票
     *
     * @param id 发票ID
     * @return 操作结果
     */
    @Override
    @Transactional
    public Result<Void> delete(Long id) {
        try {
            // 检查发票是否存在
            Invoice invoice = invoiceMapper.findById(id);
            if (invoice == null) {
                return Result.error("发票不存在");
            }

            // 保存文件路径用于后续删除
            String filePath = invoice.getFilePath();

            // 先删除与发票关联的三单匹配记录
            try {
                log.info("删除与发票ID: {}关联的三单匹配记录", id);
                jdbcTemplate.update("DELETE FROM three_way_matches WHERE invoice_id = ?", id);
            } catch (Exception e) {
                log.error("删除三单匹配记录失败", e);
                return Result.error("删除发票失败: 无法删除关联的三单匹配记录");
            }

            // 删除发票详情
            invoiceDetailMapper.deleteByInvoiceId(id);

            // 删除发票记录
            invoiceMapper.deleteById(id);

            // 事务成功后删除OSS中的文件
            if (filePath != null && !filePath.isEmpty()) {
                try {
                    // 使用AliOssUtil删除OSS中的文件
                    AliOssUtil.deleteFile(filePath);
                } catch (Exception e) {
                    // 记录删除文件失败但不影响主业务流程
                    log.error("删除OSS文件失败: {}", filePath, e);
                }
            }

            return Result.success();
        } catch (Exception e) {
            log.error("删除发票失败", e);
            return Result.error("删除发票失败: " + e.getMessage());
        }
    }

    /**
     * 根据ID查询发票
     *
     * @param id 发票ID
     * @return 发票对象
     */
    @Override
    public Result<Invoice> findById(Long id) {
        try {
            // 查询发票基本信息
            Invoice invoice = invoiceMapper.findById(id);
            if (invoice == null) {
                return Result.error("发票不存在");
            }

            // 查询发票详情
            List<InvoiceDetail> details = invoiceDetailMapper.findByInvoiceId(id);
            invoice.setDetails(details);

            return Result.success(invoice);
        } catch (Exception e) {
            log.error("查询发票失败, ID: {}", id, e);
            return Result.error("查询发票失败: " + e.getMessage());
        }
    }

//    /**
//     * 根据条件查询发票
//     *
//     * @param invoice 查询条件
//     * @return 发票列表
//     */
//    @Override
//    public Result<List<Invoice>> findByCondition(Invoice invoice) {
//        try {
//            List<Invoice> invoices = invoiceMapper.findByCondition(invoice);
//
//            // 为每个发票加载明细数据
//            if (invoices != null && !invoices.isEmpty()) {
//                for (Invoice inv : invoices) {
//                    List<InvoiceDetail> details = invoiceDetailMapper.findByInvoiceId(inv.getId());
//                    inv.setDetails(details);
//                }
//                log.info("根据条件查询到{}个发票，并已加载相关明细项", invoices.size());
//            }
//
//            return Result.success(invoices);
//        } catch (Exception e) {
//            log.error("根据条件查询发票失败", e);
//            return Result.error("根据条件查询发票失败: " + e.getMessage());
//        }
//    }

    /**
     * 根据条件Map查询发票
     *
     * @param condition 查询条件Map
     * @return 发票列表
     */
    @Override
    public List<Invoice> findByCondition(Map<String, Object> condition) {
        try {
            log.info("根据条件Map查询发票: {}", condition);

            // 创建Invoice对象
            Invoice invoice = new Invoice();

            // 设置查询条件
            if (condition.containsKey("invoiceNumber")) {
                invoice.setInvoiceNumber((String) condition.get("invoiceNumber"));
            }

            if (condition.containsKey("category")) {
                invoice.setCategory((String) condition.get("category"));
            }

            if (condition.containsKey("supplierName")) {
                invoice.setSupplierName((String) condition.get("supplierName"));
            }

            // 查询发票
            log.info("转换后的Invoice查询对象: {}", invoice);
            List<Invoice> invoices = invoiceMapper.findByCondition(invoice);
            log.info("查询结果数量: {}", invoices.size());

            // 为每个发票加载明细数据
            if (invoices != null && !invoices.isEmpty()) {
                for (Invoice inv : invoices) {
                    List<InvoiceDetail> details = invoiceDetailMapper.findByInvoiceId(inv.getId());
                    inv.setDetails(details);
                }
                log.info("已为查询到的{}个发票加载相关明细项", invoices.size());
            }

            return invoices;
        } catch (Exception e) {
            log.error("根据条件Map查询发票失败", e);
            throw new BusinessException("根据条件Map查询发票失败: " + e.getMessage());
        }
    }

//    /**
//     * 根据日期范围查询发票
//     *
//     * @param startDate 开始日期
//     * @param endDate   结束日期
//     * @return 发票列表
//     */
//    @Override
//    public Result<List<Invoice>> findByDateRange(LocalDate startDate, LocalDate endDate) {
//        try {
//            // 参数校验
//            if (startDate == null || endDate == null) {
//                return Result.error("开始日期和结束日期不能为空");
//            }
//
//            if (startDate.isAfter(endDate)) {
//                return Result.error("开始日期不能大于结束日期");
//            }
//
//            List<Invoice> invoices = invoiceMapper.findByDateRange(startDate, endDate);
//
//            // 为每个发票加载明细数据
//            if (invoices != null && !invoices.isEmpty()) {
//                for (Invoice inv : invoices) {
//                    List<InvoiceDetail> details = invoiceDetailMapper.findByInvoiceId(inv.getId());
//                    inv.setDetails(details);
//                }
//                log.info("日期范围查询到{}个发票，并已加载相关明细项", invoices.size());
//            }
//
//            return Result.success(invoices);
//        } catch (Exception e) {
//            log.error("日期范围查询发票失败", e);
//            return Result.error("日期范围查询发票失败: " + e.getMessage());
//        }
//    }

    /**
     * 根据日期范围查询发票（字符串日期格式）
     *
     * @param startDateStr 开始日期（字符串格式：yyyy-MM-dd）
     * @param endDateStr   结束日期（字符串格式：yyyy-MM-dd）
     * @return 发票列表
     */
    @Override
    public List<Invoice> findByDateRange(String startDateStr, String endDateStr) {
        try {
            LocalDate startDate = null;
            LocalDate endDate = null;

            if (startDateStr != null && !startDateStr.isEmpty()) {
                startDate = LocalDate.parse(startDateStr);
            }

            if (endDateStr != null && !endDateStr.isEmpty()) {
                endDate = LocalDate.parse(endDateStr);
            }

            // 执行查询
            List<Invoice> invoices = invoiceMapper.findByDateRange(startDate, endDate);

            // 加载发票明细
            if (invoices != null) {
                for (Invoice invoice : invoices) {
                    List<InvoiceDetail> details = invoiceDetailMapper.findByInvoiceId(invoice.getId());
                    invoice.setDetails(details);
                }
            }

            return invoices;
        } catch (Exception e) {
            log.error("根据日期范围查询发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("根据日期范围查询发票失败: " + e.getMessage(), e);
        }
    }

//    /**
//     * 上传发票文件
//     *
//     * @param file      文件
//     * @param invoiceId 发票ID
//     * @return 文件URL
//     */
//    @Override
//    public Result<String> uploadFile(MultipartFile file, Long invoiceId) {
//        try {
//            // 参数校验
//            if (file == null || file.isEmpty()) {
//                return Result.error("上传文件不能为空");
//            }
//
//            // 检查发票是否存在
//            Invoice invoice = invoiceMapper.findById(invoiceId);
//            if (invoice == null) {
//                return Result.error("发票不存在");
//            }
//
//            // 校验文件类型
//            String originalFilename = file.getOriginalFilename();
//            if (originalFilename == null) {
//                return Result.error("文件名不能为空");
//            }
//
//            String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
//            if (!".jpg".equals(suffix) && !".jpeg".equals(suffix) &&
//                    !".png".equals(suffix) && !".pdf".equals(suffix)) {
//                return Result.error("只支持jpg、jpeg、png和pdf格式的文件");
//            }
//
//            // 校验文件大小（限制为10MB）
//            long maxSize = 10 * 1024 * 1024; // 10MB
//            if (file.getSize() > maxSize) {
//                return Result.error("文件大小不能超过10MB");
//            }
//
//            // 使用AliOssUtil上传文件到阿里云OSS，指定invoice目录
//            String fileUrl = AliOssUtil.uploadFile(file, "invoice");
//            log.info("文件上传成功，URL: {}", fileUrl);
//
//            // 更新发票文件路径
//            invoice.setFilePath(fileUrl);
//            invoiceMapper.update(invoice);
//
//            return Result.success(fileUrl);
//        } catch (IOException e) {
//            log.error("上传文件失败", e);
//            return Result.error("上传文件失败: " + e.getMessage());
//        } catch (Exception e) {
//            log.error("文件处理失败", e);
//            return Result.error("文件处理失败: " + e.getMessage());
//        }
//    }

    @Override
    @Transactional
    public Invoice create(Invoice invoice) {
        log.info("开始创建发票: {}", invoice);

        // 设置初始状态和时间
        invoice.setCreateTime(LocalDateTime.now());
        //todo 暂时先把销售商作为供应商
        invoice.setSupplierName(invoice.getSellerInfo());

        // 先保存发票基本信息，获取ID
        try {
            invoiceMapper.insert(invoice);
            log.info("发票主表信息已保存，生成的ID: {}", invoice.getId());
        } catch (Exception e) {
            log.error("保存发票主表信息失败", e);
            throw new BusinessException("保存发票失败: " + e.getMessage());
        }

        // 保存发票详情信息
        List<InvoiceDetail> details = invoice.getDetails();
        if (details != null && !details.isEmpty()) {
            log.info("开始处理发票明细数据，明细数量: {}", details.size());

            // 设置发票ID并清除可能存在的旧ID
            for (InvoiceDetail detail : details) {
                // 清除可能存在的旧ID，避免主键冲突
                detail.setId(null);
                // 设置发票ID
                detail.setInvoiceId(invoice.getId());
                // 设置创建时间
                detail.setCreateTime(LocalDateTime.now());
                detail.setUpdateTime(LocalDateTime.now());
                // 记录明细数据
                log.info("处理发票明细: 项目名称=[{}], 规格型号=[{}], 单位=[{}], 数量=[{}], 单价=[{}], 金额=[{}], 税率=[{}], 税额=[{}]",
                        detail.getItemName(), detail.getSpecificationModel(), detail.getUnit(),
                        detail.getQuantity(), detail.getUnitPrice(), detail.getAmount(),
                        detail.getTaxRate(), detail.getTaxAmount());
            }

            try {
                // 批量保存
                int rows = invoiceDetailMapper.batchInsert(details);
                log.info("发票明细保存成功，影响行数: {}, 期望行数: {}", rows, details.size());

                if (rows != details.size()) {
                    log.warn("发票明细保存行数与期望不符，可能部分数据未保存成功");
                }

                // 验证明细是否真的保存成功
                List<InvoiceDetail> savedDetails = invoiceDetailMapper.findByInvoiceId(invoice.getId());
                log.info("重新查询发票明细，获取到 {} 条记录", savedDetails.size());

                if (savedDetails.isEmpty() && !details.isEmpty()) {
                    log.error("发票明细保存异常：数据未成功写入数据库");
                    throw new BusinessException("发票明细保存失败：数据未写入数据库");
                }
            } catch (Exception e) {
                log.error("保存发票明细失败", e);
                throw new BusinessException("保存发票明细失败: " + e.getMessage());
            }
        } else {
            log.warn("发票没有明细数据");
        }

        // 查询保存后的完整发票信息
        Invoice savedInvoice = invoiceMapper.findById(invoice.getId());
        // 加载明细
        List<InvoiceDetail> savedDetails = invoiceDetailMapper.findByInvoiceId(invoice.getId());
        log.info("发票创建完成，ID: {}, 查询到明细数量: {}", savedInvoice.getId(), savedDetails.size());
        savedInvoice.setDetails(savedDetails);

        return savedInvoice;
    }

    @Override
    public Invoice getById(Long id) {
        // 获取发票基本信息
        Invoice invoice = invoiceMapper.findById(id);
        if (invoice != null) {
            // 获取发票明细信息
            List<InvoiceDetail> details = invoiceDetailMapper.findByInvoiceId(id);
            log.info("发票ID: {}, 获取到明细数量: {}", id, details.size());
            invoice.setDetails(details);
        }
        return invoice;
    }

    @Override
    public List<Invoice> list() {
        List<Invoice> invoices = invoiceMapper.findAll();

        // 为每个发票加载明细数据
        if (invoices != null && !invoices.isEmpty()) {
            for (Invoice invoice : invoices) {
                List<InvoiceDetail> details = invoiceDetailMapper.findByInvoiceId(invoice.getId());
                invoice.setDetails(details);
                log.debug("为发票ID: {}加载明细项, 共{}条", invoice.getId(), details.size());
            }
        }

        return invoices;
    }

    @Override
    public List<Invoice> search(String keyword) {
        if (keyword == null || keyword.trim().isEmpty()) {
            return list(); // 已修改的list方法会加载明细项
        }

        List<Invoice> invoices = invoiceMapper.search("%" + keyword + "%");

        // 为每个发票加载明细数据
        if (invoices != null && !invoices.isEmpty()) {
            for (Invoice invoice : invoices) {
                List<InvoiceDetail> details = invoiceDetailMapper.findByInvoiceId(invoice.getId());
                invoice.setDetails(details);
            }
            log.info("关键字搜索到{}个发票，并已加载相关明细项", invoices.size());
        }

        return invoices;
    }

    @Override
    public List<Invoice> filter(String type) {
        List<Invoice> invoices = invoiceMapper.filter(type);

        // 为每个发票加载明细数据
        if (invoices != null && !invoices.isEmpty()) {
            for (Invoice invoice : invoices) {
                List<InvoiceDetail> details = invoiceDetailMapper.findByInvoiceId(invoice.getId());
                invoice.setDetails(details);
            }
            log.info("类型筛选到{}个发票，并已加载相关明细项", invoices.size());
        }

        return invoices;
    }

    @Override
    public String verify(Long id) {
        Invoice invoice = getById(id);
        if (invoice == null) {
            throw new BusinessException("发票不存在");
        }
        invoiceMapper.update(invoice);
        return "审核成功";
    }

    /**
     * 获取发票统计信息
     *
     * @return 统计信息
     */
    @Override
    public Map<String, Object> getStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        try {
            // 获取总数
            statistics.put("totalCount", invoiceMapper.countTotal());

            // 获取总金额
            statistics.put("totalAmount", invoiceMapper.sumTotalAmount());

            // 获取总税额
            statistics.put("totalTax", invoiceMapper.sumTotalTax());

            // 获取总价税合计
            statistics.put("totalAmountWithTax", invoiceMapper.sumTotalAmountWithTax());

            // 获取当月数量
            statistics.put("currentMonthCount", invoiceMapper.countByCurrentMonth());

            // 获取当月金额
            statistics.put("currentMonthAmount", invoiceMapper.sumAmountByCurrentMonth());

            // 按类别分组统计
            statistics.put("categoryStats", invoiceMapper.countGroupByCategory());

            // 供应商TOP5
            statistics.put("top5Suppliers", invoiceMapper.getTop5SuppliersByAmount());

            return statistics;
        } catch (Exception e) {
            log.error("获取发票统计信息失败", e);
            return statistics;
        }
    }

    @Override
    public PageResult<Invoice> page(PageRequest pageRequest) {
        try {
            // 构建查询参数
            Map<String, Object> params = new HashMap<>();
            params.put("pageNum", pageRequest.getPageNum());
            params.put("pageSize", pageRequest.getPageSize());

            // 设置排序
            if (pageRequest.getOrderBy() != null && !pageRequest.getOrderBy().isEmpty()) {
                params.put("orderBy", pageRequest.getOrderBy());
                params.put("orderDirection", pageRequest.getOrderDirection());
            }

            // 查询总数
            Long total = Long.valueOf(invoiceMapper.countTotal());

            // 计算偏移量
            int offset = (pageRequest.getPageNum() - 1) * pageRequest.getPageSize();
            params.put("offset", offset);

            // 分页查询
            List<Invoice> invoices = invoiceMapper.findByPage(params);

            // 查询明细
            if (invoices != null && !invoices.isEmpty()) {
                for (Invoice invoice : invoices) {
                    List<InvoiceDetail> details = invoiceDetailMapper.findByInvoiceId(invoice.getId());
                    invoice.setDetails(details);
                }
            }

            return PageResult.of(total, invoices, pageRequest.getPageSize(), pageRequest.getPageNum());
        } catch (Exception e) {
            log.error("分页查询发票失败", e);
            throw new BusinessException("分页查询发票失败: " + e.getMessage());
        }
    }

    @Override
    public Result<Void> updateFilePath(Long id, String filePath) {
        try {
            // 查询发票是否存在
            Invoice invoice = invoiceMapper.findById(id);
            if (invoice == null) {
                return Result.error("发票不存在");
            }

            // 验证文件路径
            if (filePath == null || filePath.isEmpty()) {
                return Result.error("文件路径不能为空");
            }

            // 更新文件路径
            invoice.setFilePath(filePath);
            invoiceMapper.update(invoice);

            log.info("更新发票文件路径成功，ID: {}, 路径: {}", id, filePath);
            return Result.success();
        } catch (Exception e) {
            log.error("更新发票文件路径失败", e);
            return Result.error("更新文件路径失败: " + e.getMessage());
        }
    }

//    /**
//     * 按日期统计发票
//     *
//     * @param startDate 开始日期
//     * @param endDate   结束日期
//     * @return 日期统计结果
//     */
//    @Override
//    public List<Map<String, Object>> getInvoiceDateStats(String startDate, String endDate) {
//        log.info("获取发票日期统计, 日期范围: {} - {}", startDate, endDate);
//        try {
//            // 转换日期格式
//            LocalDate start = null;
//            LocalDate end = null;
//
//            if (startDate != null && !startDate.isEmpty()) {
//                start = LocalDate.parse(startDate);
//            }
//
//            if (endDate != null && !endDate.isEmpty()) {
//                end = LocalDate.parse(endDate);
//            }
//
//            // 查询指定日期范围的发票
//            List<Invoice> invoices = invoiceMapper.findByDateRange(start, end);
//
//            // 按日期分组统计
//            Map<String, List<Invoice>> groupedByDate = invoices.stream()
//                    .collect(Collectors.groupingBy(
//                            invoice -> invoice.getIssueDate().toString()
//                    ));
//
//            // 构建统计结果
//            List<Map<String, Object>> result = new ArrayList<>();
//
//            groupedByDate.forEach((date, invoiceList) -> {
//                Map<String, Object> dateStats = new HashMap<>();
//                dateStats.put("date", date);
//                dateStats.put("count", invoiceList.size());
//
//                BigDecimal totalAmount = invoiceList.stream()
//                        .map(Invoice::getTotalAmount)
//                        .filter(Objects::nonNull)
//                        .reduce(BigDecimal.ZERO, BigDecimal::add);
//
//                BigDecimal totalTax = invoiceList.stream()
//                        .map(Invoice::getTotalTax)
//                        .filter(Objects::nonNull)
//                        .reduce(BigDecimal.ZERO, BigDecimal::add);
//
//                BigDecimal totalAmountWithTax = invoiceList.stream()
//                        .map(Invoice::getTotalAmountWithTax)
//                        .filter(Objects::nonNull)
//                        .reduce(BigDecimal.ZERO, BigDecimal::add);
//
//                dateStats.put("totalAmount", totalAmount);
//                dateStats.put("totalTax", totalTax);
//                dateStats.put("totalAmountWithTax", totalAmountWithTax);
//
//                result.add(dateStats);
//            });
//
//            // 按日期排序
//            result.sort(Comparator.comparing(item -> (String) item.get("date")));
//
//            return result;
//        } catch (Exception e) {
//            log.error("获取发票日期统计失败", e);
//            throw new BusinessException("获取发票日期统计失败: " + e.getMessage());
//        }
//    }

    @Override
    public int countTotal() {
        return invoiceMapper.countTotal();
    }

//    @Override
//    public java.math.BigDecimal sumTotalAmount() {
//        return invoiceMapper.sumTotalAmount();
//    }
//
//    @Override
//    public java.math.BigDecimal sumTotalTax() {
//        return invoiceMapper.sumTotalTax();
//    }
//
//    @Override
//    public java.math.BigDecimal sumTotalAmountWithTax() {
//        return invoiceMapper.sumTotalAmountWithTax();
//    }
//
//    @Override
//    public int countByCurrentMonth() {
//        return invoiceMapper.countByCurrentMonth();
//    }
//
//    @Override
//    public java.math.BigDecimal sumAmountByCurrentMonth() {
//        return invoiceMapper.sumAmountByCurrentMonth();
//    }
//
//    @Override
//    public List<Map<String, Object>> countGroupByCategory() {
//        return invoiceMapper.countGroupByCategory();
//    }
//
//    @Override
//    public List<Map<String, Object>> countGroupBySupplier() {
//        return invoiceMapper.countGroupBySupplier();
//    }
//
//    @Override
//    public List<Map<String, Object>> sumAmountGroupByMonth(LocalDate startDate, LocalDate endDate) {
//        return invoiceMapper.sumAmountGroupByMonth(startDate, endDate);
//    }

    @Override
    public List<Invoice> findUnmatchedInvoices(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 100; // 默认限制100条
        }
        return invoiceMapper.findUnmatchedInvoices(limit);
    }

    /**
     * 导出发票数据为Excel
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return Excel文件的字节数组
     */
    @Override
    public byte[] exportInvoices(String startDate, String endDate) {
        try {
            log.info("开始导出发票，日期范围: {} - {}", startDate, endDate);

            // 构建查询参数
            Map<String, Object> params = new HashMap<>();

            // 只有当日期不为null且不为空字符串时才添加到参数中
            if (startDate != null && !startDate.isEmpty()) {
                params.put("startDate", startDate);
            }
            if (endDate != null && !endDate.isEmpty()) {
                params.put("endDate", endDate);
            }

            // 添加分页参数，使用较大的值以获取所有数据
            params.put("offset", 0);  // 从第0条开始
            params.put("pageSize", 10000);  // 假设最多10000条数据

            // 查询发票数据
            List<Invoice> invoices = invoiceMapper.findByPage(params);
            log.info("获取到 {} 条发票数据", invoices.size());

            // 创建工作簿
            org.apache.poi.ss.usermodel.Workbook workbook = new org.apache.poi.xssf.usermodel.XSSFWorkbook();
            org.apache.poi.ss.usermodel.Sheet sheet = workbook.createSheet("发票数据");

            // 创建标题行样式
            org.apache.poi.ss.usermodel.CellStyle headerStyle = workbook.createCellStyle();
            org.apache.poi.ss.usermodel.Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);

            // 创建标题行
            org.apache.poi.ss.usermodel.Row headerRow = sheet.createRow(0);
            String[] headers = {"发票号码", "供应商", "类别", "开票日期", "金额", "税额", "价税合计", "开票人", "创建时间"};

            for (int i = 0; i < headers.length; i++) {
                org.apache.poi.ss.usermodel.Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }

            // 日期格式化
            java.time.format.DateTimeFormatter dateFormatter = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd");
            java.time.format.DateTimeFormatter dateTimeFormatter = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

            // 填充数据
            int rowNum = 1;
            for (Invoice invoice : invoices) {
                org.apache.poi.ss.usermodel.Row row = sheet.createRow(rowNum++);

                row.createCell(0).setCellValue(invoice.getInvoiceNumber());
                row.createCell(1).setCellValue(invoice.getSupplierName() != null ? invoice.getSupplierName() : "");
                row.createCell(2).setCellValue(invoice.getCategory());

                // 处理日期
                if (invoice.getIssueDate() != null) {
                    row.createCell(3).setCellValue(invoice.getIssueDate().format(dateFormatter));
                } else {
                    row.createCell(3).setCellValue("");
                }

                // 处理金额
                row.createCell(4).setCellValue(invoice.getTotalAmount() != null ? invoice.getTotalAmount().doubleValue() : 0);
                row.createCell(5).setCellValue(invoice.getTotalTax() != null ? invoice.getTotalTax().doubleValue() : 0);
                row.createCell(6).setCellValue(invoice.getTotalAmountWithTax() != null ? invoice.getTotalAmountWithTax().doubleValue() : 0);

                row.createCell(7).setCellValue(invoice.getIssuer() != null ? invoice.getIssuer() : "");

                // 处理创建时间
                if (invoice.getCreateTime() != null) {
                    row.createCell(8).setCellValue(invoice.getCreateTime().format(dateTimeFormatter));
                } else {
                    row.createCell(8).setCellValue("");
                }
            }

            // 调整列宽
            for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
            }

            // 转换为字节数组
            java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();
            workbook.write(outputStream);
            workbook.close();

            log.info("发票导出成功，总条数: {}", invoices.size());
            return outputStream.toByteArray();

        } catch (Exception e) {
            log.error("导出发票Excel出错", e);
            throw new RuntimeException("导出发票失败: " + e.getMessage(), e);
        }
    }

    /**
     * 部分更新发票信息
     *
     * @param id   发票ID
     * @param data 部分发票数据
     * @return 更新后的发票
     */
    @Override
    @Transactional
    public Invoice partialUpdate(Long id, Map<String, Object> data) {
        try {
            // 查询发票是否存在
            Invoice invoice = invoiceMapper.findById(id);
            if (invoice == null) {
                throw new RuntimeException("发票不存在，ID: " + id);
            }

            // 使用反射进行部分更新
            for (Map.Entry<String, Object> entry : data.entrySet()) {
                String fieldName = entry.getKey();
                Object value = entry.getValue();

                // 跳过null值和id字段
                if (value == null || "id".equals(fieldName)) {
                    continue;
                }

                try {
                    // 获取字段的setter方法名
                    String setterName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);

                    // 查找匹配的setter方法
                    Method[] methods = Invoice.class.getMethods();
                    for (Method method : methods) {
                        if (method.getName().equals(setterName) && method.getParameterCount() == 1) {
                            // 转换值类型
                            Class<?> paramType = method.getParameterTypes()[0];
                            Object convertedValue = convertValueToType(value, paramType);

                            // 调用setter方法
                            method.invoke(invoice, convertedValue);
                            break;
                        }
                    }
                } catch (Exception e) {
                    log.warn("设置字段 {} 值失败: {}", fieldName, e.getMessage());
                }
            }

            // 设置更新时间
            invoice.setUpdateTime(LocalDateTime.now());

            // 更新发票
            invoiceMapper.update(invoice);

            // 如果data中包含details字段，更新发票明细
            if (data.containsKey("details") && data.get("details") instanceof List) {
                updateInvoiceDetails(invoice, (List<Map<String, Object>>) data.get("details"));
            }

            // 重新查询发票，包含明细
            return getById(id);
        } catch (Exception e) {
            log.error("部分更新发票失败, ID: {}, 错误: {}", id, e.getMessage(), e);
            throw new RuntimeException("部分更新发票失败: " + e.getMessage(), e);
        }
    }

    /**
     * 将值转换为指定类型
     *
     * @param value 原始值
     * @param type  目标类型
     * @return 转换后的值
     */
    private Object convertValueToType(Object value, Class<?> type) {
        if (value == null) {
            return null;
        }

        if (type.isAssignableFrom(value.getClass())) {
            return value;
        }

        String strValue = String.valueOf(value);

        if (type == String.class) {
            return strValue;
        } else if (type == Integer.class || type == int.class) {
            return Integer.parseInt(strValue);
        } else if (type == Long.class || type == long.class) {
            return Long.parseLong(strValue);
        } else if (type == Double.class || type == double.class) {
            return Double.parseDouble(strValue);
        } else if (type == BigDecimal.class) {
            return new BigDecimal(strValue);
        } else if (type == Boolean.class || type == boolean.class) {
            return Boolean.parseBoolean(strValue);
        } else if (type == LocalDate.class) {
            return LocalDate.parse(strValue);
        } else if (type == LocalDateTime.class) {
            return LocalDateTime.parse(strValue);
        }

        return value;
    }

    /**
     * 更新发票明细
     *
     * @param invoice     发票
     * @param detailsData 明细数据
     */
    private void updateInvoiceDetails(Invoice invoice, List<Map<String, Object>> detailsData) {
        // 删除原有明细
        invoiceDetailMapper.deleteByInvoiceId(invoice.getId());

        // 添加新明细
        List<InvoiceDetail> details = new ArrayList<>();
        for (Map<String, Object> detailData : detailsData) {
            InvoiceDetail detail = new InvoiceDetail();
            detail.setInvoiceId(invoice.getId());

            // 设置明细字段
            for (Map.Entry<String, Object> entry : detailData.entrySet()) {
                String fieldName = entry.getKey();
                Object value = entry.getValue();

                if (value == null) {
                    continue;
                }

                try {
                    String setterName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                    Method[] methods = InvoiceDetail.class.getMethods();
                    for (Method method : methods) {
                        if (method.getName().equals(setterName) && method.getParameterCount() == 1) {
                            Class<?> paramType = method.getParameterTypes()[0];
                            Object convertedValue = convertValueToType(value, paramType);
                            method.invoke(detail, convertedValue);
                            break;
                        }
                    }
                } catch (Exception e) {
                    log.warn("设置明细字段 {} 值失败: {}", fieldName, e.getMessage());
                }
            }

            details.add(detail);
        }

        // 批量插入明细
        if (!details.isEmpty()) {
            invoiceDetailMapper.batchInsert(details);
        }
    }

    /**
     * 根据发票号码查询发票
     *
     * @param invoiceNumber 发票号码
     * @return 发票信息
     */
    @Override
    public Invoice findByInvoiceNumber(String invoiceNumber) {
        try {
            // 执行查询
            Invoice invoice = invoiceMapper.findByInvoiceNumber(invoiceNumber);

            // 加载发票明细
            if (invoice != null) {
                List<InvoiceDetail> details = invoiceDetailMapper.findByInvoiceId(invoice.getId());
                invoice.setDetails(details);
            }

            return invoice;
        } catch (Exception e) {
            log.error("根据发票号码查询发票失败, 发票号码: {}, 错误: {}", invoiceNumber, e.getMessage(), e);
            throw new RuntimeException("根据发票号码查询发票失败: " + e.getMessage(), e);
        }
    }

    /**
     * 批量删除发票
     *
     * @param ids 发票ID列表
     * @return 是否删除成功
     */
    @Override
    @Transactional
    public boolean batchDelete(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }

        try {
            int rows = invoiceMapper.batchDelete(ids);
            return rows > 0;
        } catch (Exception e) {
            log.error("批量删除发票失败: {}", e.getMessage());
            return false;
        }
    }

    @Override
    public List<Order> getRelatedOrders(Long id) {
        if (id == null) {
            return Collections.emptyList();
        }

        try {
            Invoice invoice = invoiceMapper.findById(id);
            if (invoice == null) {
                log.warn("查询关联订单失败：发票不存在，ID: {}", id);
                return Collections.emptyList();
            }

            // 如果发票有直接关联的订单ID
            if (invoice.getOrderId() != null) {
                Order order = orderService.getOrderById(invoice.getOrderId());
                if (order != null) {
                    return Collections.singletonList(order);
                }
            }

            // 通过三单匹配关系查找关联的订单
            List<Order> orders = matchService.getOrdersByInvoiceId(id);
            if (orders != null && !orders.isEmpty()) {
                log.info("通过三单匹配关系找到发票关联的订单，发票ID: {}, 找到订单数量: {}", id, orders.size());
                return orders;
            }

            log.info("未找到发票关联的订单，发票ID: {}", id);
            return Collections.emptyList();
        } catch (Exception e) {
            log.error("获取发票关联订单异常，发票ID: {}", id, e);
            return Collections.emptyList();
        }
    }
} 